package admin

import (
	"night-school-api/models"
	"night-school-api/utils"
	"night-school-api/database"

	"strconv"
	"fmt"
	"encoding/json"
	"github.com/labstack/echo/v4"
	"gorm.io/gorm"
)

type updateEnrollmentRequest struct {
	ID          int      `json:"id" gorm:"-" validate:"required,gte=1"`
	Status      models.AuditStatus   `json:"status" gorm:"column:status;" validate:"required,gte=0,lte=2"`
}

func GetEnrollments(c echo.Context) error {
	// 审核状态
	status, err := strconv.Atoi(c.QueryParam("status"))
	if err != nil {
		status = -1
	}
	if status < -1 || status > 2 {
		return utils.JSONError(c, "参数错误")
	}

	courseId, err := strconv.Atoi(c.QueryParam("course_id"))
	if err != nil {
		courseId = 0
	}
	if courseId < 1 {
		return utils.JSONError(c, "参数错误")
	}

	db := database.DB
	var course models.Course
	db.First(&course, courseId)
	if course.ID < 1 {
		return utils.JSONError(c, "未找到该课程")
	}
	if course.Status != models.AuditApproved {
		return utils.JSONError(c, "该课程未通过审核")
	}

	query := db.Model(&models.Enrollment{}).Where("course_id =?", courseId)
	if status != -1 {
		query = query.Where("status = ?", status)
	}

	order := "id DESC"
	

	var total int64
	var enrollments []models.EnrollmentRecord
	query.Count(&total)
	page, size := utils.GetPagination(c)
	query.Order(order).Preload("User").Limit(size).Offset((page - 1) * size).Find(&enrollments)


	return utils.JSONPagination(c, page, size, total, enrollments)
}

func UpdateEnrollment(c echo.Context) error {

	var req updateEnrollmentRequest

	if err := c.Bind(&req); err != nil {
		return utils.JSONError(c, "请求参数错误")
	}

	db := database.DB
	var enrollment models.Enrollment
	db.First(&enrollment, req.ID)

	if enrollment.ID <= 0 {
		return utils.JSONError(c, "操作失败，请刷新重试")
	}

	var course models.Course
	db.First(&course, enrollment.CourseID)

	if course.ID <= 0 {
		return utils.JSONError(c, "操作失败，请刷新重试")
	}
	
	statusChanged := false
	if enrollment.Status != req.Status {
		statusChanged = true
	}

	// c.Logger().Info(fmt.Sprintf("req: %v", req))

	
	err := db.Transaction(func(tx *gorm.DB) error {
		// 更新报名状态
		if err := tx.Model(&enrollment).Updates(map[string]interface{}{"status": req.Status}).Error; err != nil {
			return err // 事务回滚
		}

		// 更新课程已审核通过报名人数
		if statusChanged {
			enrollApprovedAmount := course.EnrollApprovedAmount
			if req.Status == models.AuditApproved {
				enrollApprovedAmount += 1
			} else {
				enrollApprovedAmount -= 1
			}
			
			if err := tx.Model(&course).Update("enroll_approved_amount", enrollApprovedAmount).Error; err != nil {
				return err // 事务回滚
			}
		}

		return nil // 事务提交
	})

	
	if err != nil {
		c.Logger().Info("修改报名失败: " + err.Error())
		return utils.JSONError(c, "修改报名失败")
	} else {
		if statusChanged && enrollment.Status == models.AuditApproved && enrollment.IsAuditApprovedSubscribed == 1 {
			// 给学生发送报名审核通过的订阅消息
			
			var user models.User
			db.First(&user, enrollment.UserID)

			var course models.Course
			db.First(&course, enrollment.CourseID)
			// c.Logger().Info(fmt.Sprintf("course: %#v", course))
			// c.Logger().Info(fmt.Sprintf("user: %#v", user))

			if course.ID > 0 && len(user.Openid) > 0 {

				// 上课地址
				var address string
				addressJson := course.Address
				var addr map[string]interface{}
				err := json.Unmarshal([]byte(addressJson), &addr)
				if err == nil {
					addressStr, ok := addr["name"].(string)
					if ok {
						address = addressStr
					}
				}

				startAtStr := course.StartAt.Format("2006-01-02 15:04")
				statuZh := "您的课程报名已审核通过，请记得按时上课"

				err = utils.EnrollmentAuditApprovedSendMsg(c, course.ID, user.Openid, course.Name, course.TeacherName,  startAtStr, address, statuZh)
				c.Logger().Info(fmt.Sprintf("EnrollmentAuditApprovedSendMsg() err: %#v", err))
			}
		}

		return utils.JSONSuccess(c, nil, "修改报名成功")
	}
}